using MediatR;
using Microsoft.Extensions.Logging;
using S.O.Api.Write.Application.Command.Medical;
using S.O.Domain.Medical;
using S.O.ErrorCode;
using S.O.Interstructrue.Base;
using Yitter.IdGenerator;

namespace S.O.Api.Write.Application.Handler.Medical
{
    /// <summary>
    /// 创建西药处方处理器
    /// 负责处理西药处方创建的业务逻辑，包括数据验证、处方记录创建和持久化
    /// </summary>
    public class CreateWesternMedicinePrescriptionHandler : IRequestHandler<CreateWesternMedicinePrescriptionCommand, APIResult<string>>
    {
        /// <summary>
        /// 处方信息仓储接口
        /// </summary>
        private readonly IBaseRepository<PrescriptionModel> _prescriptionRepository;

        /// <summary>
        /// 处方药品明细仓储接口
        /// </summary>
        private readonly IBaseRepository<PrescriptionMedicineModel> _prescriptionMedicineRepository;

        /// <summary>
        /// 患者信息仓储接口
        /// </summary>
        private readonly IBaseRepository<PatientModel> _patientRepository;

        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger<CreateWesternMedicinePrescriptionHandler> _logger;

        /// <summary>
        /// 构造函数，通过依赖注入初始化仓储和日志服务
        /// </summary>
        /// <param name="prescriptionRepository">处方信息仓储</param>
        /// <param name="prescriptionMedicineRepository">处方药品明细仓储</param>
        /// <param name="patientRepository">患者信息仓储</param>
        /// <param name="logger">日志记录器</param>
        public CreateWesternMedicinePrescriptionHandler(
            IBaseRepository<PrescriptionModel> prescriptionRepository,
            IBaseRepository<PrescriptionMedicineModel> prescriptionMedicineRepository,
            IBaseRepository<PatientModel> patientRepository,
            ILogger<CreateWesternMedicinePrescriptionHandler> logger)
        {
            _prescriptionRepository = prescriptionRepository;
            _prescriptionMedicineRepository = prescriptionMedicineRepository;
            _patientRepository = patientRepository;
            _logger = logger;
        }

        /// <summary>
        /// 处理创建西药处方命令
        /// </summary>
        /// <param name="request">创建西药处方命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>包含处方ID的API结果</returns>
        public async Task<APIResult<string>> Handle(CreateWesternMedicinePrescriptionCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始处理创建西药处方请求，患者ID: {PatientId}, 医生: {Doctor}", request.PatientId, request.Doctor);

                // 验证请求参数
                var validationResult = await ValidateRequest(request);
                if (validationResult.Code != APIEnums.Success)
                {
                    return validationResult;
                }

                // 生成处方ID
                var prescriptionId = GeneratePrescriptionId();

                // 创建处方记录
                var prescription = new PrescriptionModel
                {
                    Id = prescriptionId,
                    PatientId = request.PatientId,
                    PatientName = request.PatientName,
                    PrescriptionType = "西药",
                    Diagnosis = request.Diagnosis,
                    Remark = request.Remark,
                    Doctor = request.Doctor,
                    Status = "已开具",
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now,
                    IsEnable = true,
                    CreateUser = request.Doctor,
                    IsDeleted = false
                };

                // 保存处方记录
                _prescriptionRepository.Create(prescription);

                // 创建处方药品明细
                var medicines = new List<PrescriptionMedicineModel>();
                for (int i = 0; i < request.Medicines.Count; i++)
                {
                    var medicineItem = request.Medicines[i];
                    var medicine = new PrescriptionMedicineModel
                    {
                        Id = YitIdHelper.NextId(),
                        PrescriptionId = prescriptionId,
                        MedicineName = medicineItem.MedicineName,
                        Specification = medicineItem.Specification,
                        Dosage = medicineItem.Dosage,
                        Frequency = medicineItem.Frequency,
                        Duration = medicineItem.Duration,
                        Usage = medicineItem.Usage,
                        Remark = medicineItem.Remark,
                        SortOrder = i + 1,
                        CreateTime = DateTime.Now,
                        UpdateTime = DateTime.Now,
                        IsEnable = true,
                        CreateUser = request.Doctor,
                        IsDeleted = false
                    };
                    medicines.Add(medicine);
                }

                // 批量保存药品明细
                foreach (var medicine in medicines)
                {
                    _prescriptionMedicineRepository.Create(medicine);
                }

                _logger.LogInformation("西药处方创建成功，处方ID: {PrescriptionId}, 患者: {PatientName}, 医生: {Doctor}", 
                    prescriptionId, request.PatientName, request.Doctor);

                return new APIResult<string>
                {
                    Code = APIEnums.Success,
                    Data = prescriptionId,
                    Msg = "西药处方开具成功"
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建西药处方时发生错误，患者ID: {PatientId}, 医生: {Doctor}", request.PatientId, request.Doctor);
                return new APIResult<string>
                {
                    Code = APIEnums.Error,
                    Msg = "创建西药处方失败，请稍后重试"
                };
            }
        }

        /// <summary>
        /// 验证请求参数
        /// </summary>
        /// <param name="request">创建西药处方命令</param>
        /// <returns>验证结果</returns>
        private async Task<APIResult<string>> ValidateRequest(CreateWesternMedicinePrescriptionCommand request)
        {
            // 验证患者是否存在
            var patient = _patientRepository.GetModel(request.PatientId);
            if (patient == null || patient.IsDeleted)
            {
                return new APIResult<string>
                {
                    Code = APIEnums.Error,
                    Msg = "患者信息不存在"
                };
            }

            // 验证药品列表
            if (request.Medicines == null || !request.Medicines.Any())
            {
                return new APIResult<string>
                {
                    Code = APIEnums.Error,
                    Msg = "药品列表不能为空"
                };
            }

            // 验证每个药品项
            foreach (var medicine in request.Medicines)
            {
                if (string.IsNullOrWhiteSpace(medicine.MedicineName))
                {
                    return new APIResult<string>
                    {
                        Code = APIEnums.Error,
                        Msg = "药品名称不能为空"
                    };
                }
                if (string.IsNullOrWhiteSpace(medicine.Specification))
                {
                    return new APIResult<string>
                    {
                        Code = APIEnums.Error,
                        Msg = "药品规格不能为空"
                    };
                }
                if (string.IsNullOrWhiteSpace(medicine.Dosage))
                {
                    return new APIResult<string>
                    {
                        Code = APIEnums.Error,
                        Msg = "剂量不能为空"
                    };
                }
                if (string.IsNullOrWhiteSpace(medicine.Frequency))
                {
                    return new APIResult<string>
                    {
                        Code = APIEnums.Error,
                        Msg = "频次不能为空"
                    };
                }
                if (string.IsNullOrWhiteSpace(medicine.Duration))
                {
                    return new APIResult<string>
                    {
                        Code = APIEnums.Error,
                        Msg = "疗程不能为空"
                    };
                }
                if (string.IsNullOrWhiteSpace(medicine.Usage))
                {
                    return new APIResult<string>
                    {
                        Code = APIEnums.Error,
                        Msg = "用法不能为空"
                    };
                }
            }

            return new APIResult<string>
            {
                Code = APIEnums.Success,
                Data = "",
                Msg = "验证通过"
            };
        }

        /// <summary>
        /// 生成处方ID
        /// 格式：PR + 年月日 + 6位序号
        /// </summary>
        /// <returns>处方ID</returns>
        private string GeneratePrescriptionId()
        {
            var dateStr = DateTime.Now.ToString("yyyyMMdd");
            var sequence = DateTime.Now.ToString("HHmmss");
            return $"PR{dateStr}{sequence}";
        }
    }
}